import asyncio
import json
import os
import sys
import pymysql
import datetime as d
from datetime import datetime
from langchain.agents import OpenAIMultiFunctionsAgent, create_openai_tools_agent
from langchain_core.output_parsers import JsonOutputParser, StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
# from config import OPENAI_API_KEY
from prompt.choice_questions_analysis import CHOICES_ANALYSIS_PROMPT
from prompt.composition_analysis import ESSAY_ANALYSIS_PROMPT
from prompt.demension_evaluation import DIMENSION_EVALUATION_PROMPT
from prompt.overview import OVERVIEW_PROMPT
from prompt.reading_comprehension_analysis import (
    READING_COMPREHENSION_RESULTS_ANALYSIS_PROMPT,
)
from prompt.translatation_analysis import TRANSLATION_ANALYSIS_PROMPT

os.environ["http_proxy"] = "http://127.0.0.1:10808"
os.environ["https_proxy"] = "http://127.0.0.1:10808"
OPENAI_API_KEY = "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"

quiz_data_example = {
    "choice_questions": {
        "total_questions": 20,
        "correct_answers": 15,
        "incorrect_analysis": [
            "Misunderstood the question",
            "Calculation error",
            "Incorrect formula used",
        ],
    },
    "reading_comprehension": [
        {
            "error_analysis": "Misunderstood the question",
            "correct_answer_explanation": "The correct answer is B because...",
            "suggestions": "Review the question carefully before answering.",
        }
    ],
    "translation": [
        {
            "total_score": 8,
            "accuracy_score": 8,
            "accuracy_reason": "Good understanding of the text.",
            "fluency_score": 7,
            "fluency_reason": "Generally smooth, with minor errors.",
            "grammar_score": 8,
            "grammar_reason": "Minor grammatical mistakes, but overall good.",
        },
        {
            "total_score": 7,
            "accuracy_score": 7,
            "accuracy_reason": "Adequate understanding with some mistakes.",
            "fluency_score": 6,
            "fluency_reason": "Some awkward phrasing.",
            "grammar_score": 7,
            "grammar_reason": "Several grammatical errors.",
        },
    ],
    "essay": [
        {
            "content_score": 8,
            "content_comment": "The essay well addresses the topic, with comprehensive arguments.",
            "organization_score": 7,
            "organization_comment": "Well-organized overall, though transitions between paragraphs could be smoother.",
            "grammar_score": 8,
            "grammar_comment": "Minor grammatical errors, but overall good use of English.",
            "detailed_suggestions": [
                "Consider using more varied sentence structures to enhance readability.",
                "Revisit the transitions between paragraphs for smoother flow.",
            ],
        },
        {
            "content_score": 8,
            "content_comment": "内容基本符合信件要求，清晰表达了写信目的、个人优势和能做的事情，但可以进一步展开描述个人优势和能做的事情的细节",
            "organization_score": 7,
            "organization_comment": "组织结构较为简洁明了，但可以考虑在每个部分中增加更多细节，使文章更具连贯性和逻辑性",
            "grammar_score": 9,
            "grammar_comment": "语法基本正确，用词恰当，标点准确，表达清晰",
            "detailed_suggestions": [
                "建议在个人优势和能做的事情部分增加具体的例子或经历，以更具说服力和展示自身实力",
                "可以在信件结尾处再次表达对志愿者机会的热切期待，增加感情色彩",
                "继续保持语法和用词准确性，可以尝试丰富词汇，提升表达的多样性",
            ],
        },
    ],
}

quiz_data_example_v2 = {
    "choice_questions": {
        "total_questions": 20,
        "correct_answers": 15,
        "incorrect_analysis": "Misunderstood the question, Calculation error,Incorrect formula used",
    },
    "reading_comprehension": [
        {
            "comment": """Misunderstood the question
                        The correct answer is B because...
                        Review the question carefully before answering.
                        """
        },
        {
            "comment": """学生可能选择错误答案A的原因是因为他们没有理解文章中作者是如何引入话题的。文章开头通过Bob Fitzgerald的观察和经历来引入话题，而不是通过进行比较、调查或研究原因。
                        正确答案B是由作者通过展示Bob Fitzgerald的经历来引入话题，从而让读者对气候变化对农业的影响有直观的了解。
                        建议学生在阅读理解时要注意文章的开头部分，尤其是作者是如何引入话题的。理解作者的意图对于正确回答问题至关重要。建议学生多加练习阅读文章并尝试从中抓住作者的引入话题的方法。
                        """
        },
    ],
    "translation": [
        {
            "total_score": 8,
            "accuracy_score": 8,
            "accuracy_reason": "Good understanding of the text.",
            "fluency_score": 7,
            "fluency_reason": "Generally smooth, with minor errors.",
            "grammar_score": 8,
            "grammar_reason": "Minor grammatical mistakes, but overall good.",
        },
        {
            "total_score": 7,
            "accuracy_score": 7,
            "accuracy_reason": "Adequate understanding with some mistakes.",
            "fluency_score": 6,
            "fluency_reason": "Some awkward phrasing.",
            "grammar_score": 7,
            "grammar_reason": "Several grammatical errors.",
        },
    ],
    "essay": [
        {
            "content_score": 8,
            "content_comment": "The essay well addresses the topic, with comprehensive arguments.",
            "organization_score": 7,
            "organization_comment": "Well-organized overall, though transitions between paragraphs could be smoother.",
            "grammar_score": 8,
            "grammar_comment": "Minor grammatical errors, but overall good use of English.",
            "detailed_suggestions": """Consider using more varied sentence structures to enhance readability.
                Revisit the transitions between paragraphs for smoother flow.""",
        },
        {
            "content_score": 8,
            "content_comment": "内容基本符合信件要求，清晰表达了写信目的、个人优势和能做的事情，但可以进一步展开描述个人优势和能做的事情的细节",
            "organization_score": 7,
            "organization_comment": "组织结构较为简洁明了，但可以考虑在每个部分中增加更多细节，使文章更具连贯性和逻辑性",
            "grammar_score": 9,
            "grammar_comment": "语法基本正确，用词恰当，标点准确，表达清晰",
            "detailed_suggestions": """建议在个人优势和能做的事情部分增加具体的例子或经历，以更具说服力和展示自身实力',
                                     '可以在信件结尾处再次表达对志愿者机会的热切期待，增加感情色彩',
                                     '继续保持语法和用词准确性，可以尝试丰富词汇，提升表达的多样性""",
        },
    ],
}
timestamp_sunday = ""
timestamp_monday = ""
formatted_monday = ""
formatted_sunday = ""
essay = []
translation = []
reading_comprehension = []
total_questions = 0
correct_answers = 0
incorrect_analysis = ""
userIDs = []


# 设置上周一和周日的日期
def setTime():

    global formatted_monday
    global formatted_sunday
    global timestamp_monday
    global timestamp_sunday
    # 获取当前日期和时间
    now = d.datetime.now()
    # 计算当前日期是本周的第几天（0代表周一，1代表周二，以此类推）
    weekday = now.weekday()
    # 计算上周一的日期
    last_monday = now - d.timedelta(days=weekday + 7)
    # 计算上周日的日期
    last_sunday = last_monday + d.timedelta(days=6)
    # 将时间设置为零点
    last_monday = last_monday.replace(hour=0, minute=0, second=0, microsecond=0)
    last_sunday = last_sunday.replace(hour=23, minute=59, second=59, microsecond=999999)
    # 获取时间戳
    timestamp_monday = int(last_monday.timestamp())
    timestamp_sunday = int(last_sunday.timestamp())
    # 将时间戳转换为日期时间对象
    monday = datetime.fromtimestamp(timestamp_monday)
    sunday = datetime.fromtimestamp(timestamp_sunday)
    # 将日期时间对象格式化为字符串形式
    formatted_monday = monday.strftime("%Y-%m-%d %H:%M:%S")
    formatted_sunday = sunday.strftime("%Y-%m-%d %H:%M:%S")


def dataBaseGetStudent():
    global userIDs
    # 连接数据库，创建连接对象connection
    # 连接对象作用是：连接数据库、发送数据库信息、处理回滚操作（查询中断时，数据库回到最初状态）、创建新的光标对象
    connection = pymysql.connect(
        host="www.yym-free.com",
        user="fuchuang",
        password="fuchuang",
        db="fuchuang",
        port=3306,
    )
    cur = connection.cursor()
    # 获取全部食品的信息
    cur.execute("SELECT id from user")
    all = cur.fetchall()
    # 将所有学生的ID封装到list中
    for i in all:
        userIDs.append(i[0])

    connection.commit()
    connection.close()


def dataBaseExe(userID):
    global essay
    global translation
    global reading_comprehension
    global total_questions
    global correct_answers
    global incorrect_analysis
    # 连接数据库，创建连接对象connection
    # 连接对象作用是：连接数据库、发送数据库信息、处理回滚操作（查询中断时，数据库回到最初状态）、创建新的光标对象
    connection = pymysql.connect(
        host="www.yym-free.com",
        user="fuchuang",
        password="fuchuang",
        db="fuchuang",
        port=3306,
    )
    cur = connection.cursor()
    # 获取全部食品的信息
    cur.execute(
        "SELECT e.category,k.isRight,k.compCommentID,k.transCommentID,k.falsereason,k.aiComment FROM recorddetail as k,exercise as e WHERE"
        + " e.id=k.exerciseID and k.stuID =%s and k.insertTime>=%s and k.insertTime<=%s",
        (
            userID,
            formatted_monday,
            formatted_sunday,
        ),
    )
    all = cur.fetchall()
    for i in all:
        category = i[0]
        if category == "xuanze":
            total_questions = total_questions + 1
            incorrect_analysis += i[4]
            if i[1] == 1:
                correct_answers += 1
        elif category == "yuedu":
            if i[5] != None:
                new_item = {"comment": i[5]}
                reading_comprehension.append(new_item)
        elif category == "fanyi":
            tranID = i[3]
            # print(tranID)
            # print(type(tranID))
            cur2 = connection.cursor()
            # 获取评价的具体信息
            cur2.execute(
                "SELECT * from translatedetail where id=%s",
                (tranID,),
            )
            row = cur2.fetchone()
            # print(row)
            new_item = {
                "accuracy_score": row[1],
                "accuracy_reason": row[2],
                "fluency_score": row[3],
                "fluency_reason": row[4],
                "grammar_score": row[5],
                "grammar_reason": row[6],
                "total_score": row[1] + row[3] + row[5],
            }
            translation.append(new_item)
        else:
            essayID = i[2]
            cur2 = connection.cursor()
            # 获取评价的具体信息
            cur2.execute(
                "SELECT * from compositiondetail where id=%s",
                (essayID,),
            )
            row = cur2.fetchone()
            new_item = {
                "content_score": row[1],
                "content_comment": row[2],
                "grammar_score": row[3],
                "grammar_comment": row[4],
                "organization_score": row[5],
                "organization_comment": row[6],
                "detailed_suggestions": i[5],
            }
            essay.append(new_item)

    connection.commit()
    connection.close()
    # print(list)


def dataBaseRedo(userID):
    global essay
    global translation
    global reading_comprehension
    global total_questions
    global correct_answers
    global incorrect_analysis
    # 连接数据库，创建连接对象connection
    # 连接对象作用是：连接数据库、发送数据库信息、处理回滚操作（查询中断时，数据库回到最初状态）、创建新的光标对象
    connection = pymysql.connect(
        host="www.yym-free.com",
        user="fuchuang",
        password="fuchuang",
        db="fuchuang",
        port=3306,
    )
    cur = connection.cursor()
    # 获取全部食品的信息
    cur.execute(
        "SELECT c.category,r.redoRight,r.redoCompositionID,r.redoTranslationID,r.falsereason,r.redoAIComment FROM cuotiji as c,redorecord as r "
        + "WHERE c.id=r.cuotiID and c.stuID=%s and r.redoTime>=%s and r.redoTime<=%s",
        (
            userID,
            formatted_monday,
            formatted_sunday,
        ),
    )
    all = cur.fetchall()
    for i in all:
        category = i[0]
        if category == "xuanze":
            total_questions = total_questions + 1
            if i[4] != None:
                incorrect_analysis += i[4]
            if i[1] == 1:
                correct_answers += 1
        elif category == "yuedu":
            if i[5] != None:
                new_item = {"comment": i[5]}
                reading_comprehension.append(new_item)
        elif category == "fanyi":
            tranID = i[3]
            cur2 = connection.cursor()
            # 获取评价的具体信息
            cur2.execute(
                "SELECT * from translatedetail where id=%s",
                (tranID,),
            )
            row = cur2.fetchone()
            new_item = {
                "accuracy_score": row[1],
                "accuracy_reason": row[2],
                "fluency_score": row[3],
                "fluency_reason": row[4],
                "grammar_score": row[5],
                "grammar_reason": row[6],
                "total_score": row[1] + row[3] + row[5],
            }
            translation.append(new_item)
        else:
            essayID = i[2]
            cur2 = connection.cursor()
            # 获取评价的具体信息
            cur2.execute(
                "SELECT * from compositiondetail where id=%s",
                (essayID,),
            )
            row = cur2.fetchone()
            new_item = {
                "content_score": row[1],
                "content_comment": row[2],
                "grammar_score": row[3],
                "grammar_comment": row[4],
                "organization_score": row[5],
                "organization_comment": row[6],
                "detailed_suggestions": i[5],
            }
            essay.append(new_item)

    connection.commit()
    connection.close()
    # print(list)


async def evaluate_choice_questions_performance(input_data) -> dict:
    # 构建选择题评价的prompt
    prompt_template = ChatPromptTemplate.from_template(CHOICES_ANALYSIS_PROMPT)
    # 调用LLM
    llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY)
    json_parser = JsonOutputParser()
    chain = prompt_template | llm | json_parser
    evaluation_result = await chain.ainvoke(
        {
            "total_questions": input_data["total_questions"],
            "correct_answers": input_data["correct_answers"],
            "accuracy_percentage": round(
                input_data["correct_answers"] / input_data["total_questions"] * 100, 2
            ),
            "incorrect_analysis": input_data["incorrect_analysis"],
        }
    )
    # print(evaluation_result)

    return evaluation_result


async def evaluate_reading_comprehension_performance(
    reading_comprehension_results: list,
):
    # 将阅读理解结果列表转换为JSON格式的字符串
    combined_comments = "\n".join(
        [item["comment"] for item in reading_comprehension_results]
    )
    prompt_template = ChatPromptTemplate.from_template(
        READING_COMPREHENSION_RESULTS_ANALYSIS_PROMPT
    )
    # 调用LLM
    llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY)
    json_parser = JsonOutputParser()
    chain = prompt_template | llm | json_parser
    evaluation_result = await chain.ainvoke(
        {"reading_comprehension_results": combined_comments}
    )
    # print(evaluation_result)

    return evaluation_result


async def evaluate_translation_performance(translation_results: list):
    # 将翻译结果列表转换为JSON格式的字符串
    formatted_translation_results = json.dumps(
        translation_results, ensure_ascii=False, indent=2
    )

    prompt_template = ChatPromptTemplate.from_template(TRANSLATION_ANALYSIS_PROMPT)
    # 调用LLM
    llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY)
    json_parser = JsonOutputParser()
    chain = prompt_template | llm | json_parser
    evaluation_result = await chain.ainvoke(
        {"translation_results": formatted_translation_results}
    )
    # print(evaluation_result)

    return evaluation_result


async def evaluate_essay_performance(essay_data: dict):
    # 构建作文评价的prompt
    prompt_template = ChatPromptTemplate.from_template(ESSAY_ANALYSIS_PROMPT)
    formatted_essay_results = json.dumps(essay_data, ensure_ascii=False, indent=2)
    # 调用LLM
    llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY)
    json_parser = JsonOutputParser()
    chain = prompt_template | llm | json_parser
    evaluation_result = await chain.ainvoke({"essay_results": formatted_essay_results})
    # print(evaluation_result)
    return evaluation_result


async def overall_performance_analysis(
    choice_evaluation,
    reading_comprehension_evaluation,
    translation_evaluation,
    essay_evaluation,
):
    # 将各部分评价合并为一个字符串
    evaluations_summary = (
        f"Choice Questions: {choice_evaluation['performance']}\n"
        f"Reading Comprehension: {reading_comprehension_evaluation['performance']}\n"
        f"Translation: {translation_evaluation['performance']}\n"
        f"Essay: {essay_evaluation['performance']}\n"
    )

    # 提出综合建议
    suggestions = (
        choice_evaluation.get("suggestions", [])
        + reading_comprehension_evaluation.get("suggestions", [])
        + translation_evaluation.get("suggestions", [])
        + essay_evaluation.get("suggestions", [])
    )

    # print(evaluations_summary, suggestions)
    prompt_template_overview = ChatPromptTemplate.from_template(OVERVIEW_PROMPT)
    prompt_template_dimension = ChatPromptTemplate.from_template(
        DIMENSION_EVALUATION_PROMPT
    )
    llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY)
    output_parser = JsonOutputParser()
    chain_overview = prompt_template_overview | llm | output_parser
    chain_dimension = prompt_template_dimension | llm | output_parser
    overview_result = await chain_overview.ainvoke(
        {
            "performance_combination": evaluations_summary,
            "suggestions_combination": suggestions,
        }
    )
    dimension_result = await chain_dimension.ainvoke(
        {
            "performance_combination": evaluations_summary,
            "suggestions_combination": suggestions,
        }
    )

    # 组装返回结果
    return {"overview_result": overview_result, "dimension_result": dimension_result}


async def analyze_quiz_performance(quiz_data: dict) -> dict:
    """
    这个函数分析测验的表现，并提供对答案的分析。

    参数:
    quiz_data (dict): 包含测验数据的字典。

    返回:
    dict: 包含评估成功状态、分析和建议以及在评估过程中出现的任何错误的字典。
    """
    try:
        (
            choice_result,
            reading_comprehension_result,
            translation_result,
            essay_result,
        ) = await asyncio.gather(
            evaluate_choice_questions_performance(quiz_data["choice_questions"]),
            evaluate_reading_comprehension_performance(
                quiz_data["reading_comprehension"]
            ),
            evaluate_translation_performance(quiz_data["translation"]),
            evaluate_essay_performance(quiz_data["essay"]),
        )
        performance_dict = await overall_performance_analysis(
            choice_result,
            reading_comprehension_result,
            translation_result,
            essay_result,
        )
        overall_evaluation = performance_dict.get("overview_result", None)
        dimension_evaluation = performance_dict.get("dimension_result", None)
        data = {
            "startTimeStr": formatted_monday,
            "endTimeStr": formatted_sunday,
            "overlevel": overall_evaluation.get("overall_performance_score", 5.0),
            "overEvaluation": overall_evaluation.get(
                "overall_performance_comment", None
            ),
            "lanCompreScore": dimension_evaluation["language_comprehension"]["score"],
            "lanCompreComment": dimension_evaluation["language_comprehension"][
                "comment"
            ],
            "lanExpreScore": dimension_evaluation["language_expression"]["score"],
            "lanExpreComment": dimension_evaluation["language_expression"]["comment"],
            "lanKnowledgeScore": dimension_evaluation["language_knowledge"]["score"],
            "lanKnowledgeComment": dimension_evaluation["language_knowledge"][
                "comment"
            ],
            "choicePerformance": choice_result.get("performance", None),
            "choiceSuggestion": choice_result.get("suggestions", None),
            "readingPerformance": reading_comprehension_result.get("performance", None),
            "readingSuggestion": reading_comprehension_result.get("suggestions", None),
            "TranslationPerformance": translation_result.get("performance", None),
            "TranslationSuggestion": translation_result.get("suggestions", None),
            "essayPerformance": essay_result.get("performance", None),
            "essaySuggestion": essay_result.get("suggestions", None),
        }
        # return {
        #     "success": True,
        #     "analysis_and_advice": {
        #         "overall_performance_score": overall_evaluation.get(
        #             "overall_performance_score", 5.0
        #         ),
        #         "overall_performance_comment": overall_evaluation.get(
        #             "overall_performance_comment", None
        #         ),
        #         "dimension": dimension_evaluation,
        #         "evaluations": [
        #             {
        #                 "question_type": "Choice Questions",
        #                 "performance": choice_result.get("performance", None),
        #                 "suggestions": choice_result.get("suggestions", None),
        #             },
        #             {
        #                 "question_type": "Reading Comprehension",
        #                 "performance": reading_comprehension_result.get(
        #                     "performance", None
        #                 ),
        #                 "suggestions": reading_comprehension_result.get(
        #                     "suggestions", None
        #                 ),
        #             },
        #             {
        #                 "question_type": "Translation",
        #                 "performance": translation_result.get("performance", None),
        #                 "suggestions": translation_result.get("suggestions", None),
        #             },
        #             {
        #                 "question_type": "Essay",
        #                 "performance": essay_result.get("performance", None),
        #                 "suggestions": essay_result.get("suggestions", None),
        #             },
        #         ],
        #     },
        # }
        print(str(data))
    except Exception as e:
        print(e)
        # return {"success": False, "analysis_and_advice": None, "error": str(e)}


async def analyze_quiz_performance_smalltest(quiz_data: dict) -> dict:
    try:
        choice_result, translation_result = await asyncio.gather(
            evaluate_choice_questions_performance(quiz_data["choice_questions"]),
            evaluate_translation_performance(quiz_data["translation"]),
        )
        overview_result = overall_performance_analysis(
            choice_result, translation_result, quiz_data["essay"]
        )
        # data = {}
        return {
            "success": True,
            "analysis_and_advice": {
                "overall_performance": "test",
                "evaluations": [
                    {
                        "question_type": "Choice Questions",
                        "performance": choice_result["performance"],
                        "suggestions": choice_result["suggestions"],
                    },
                    {
                        "question_type": "Translation",
                        "performance": translation_result["performance"],
                        "suggestions": translation_result["suggestions"],
                    },
                ],
            },
        }
    except Exception as e:
        return {"success": False, "analysis_and_advice": None, "error": str(e)}


async def main():
    await analyze_quiz_performance(quiz_data_example_v2)
    # print(result)


if __name__ == "__main__":
    setTime()
    # dataBaseGetStudent()
    # 接收参数
    userID = sys.argv[1]
    # userID = 18
    userID = int(userID)
    # 获取用户重做的记录和练习的记录
    dataBaseExe(userID)
    dataBaseRedo(userID)
    # 如果本周做题记录为空 则不需要进行任何分析
    if (
        total_questions == 0
        and not reading_comprehension
        and not essay
        and not translation
    ):
        data = {"startTimeStr": formatted_monday, "endTimeStr": formatted_sunday}
        print(data)
    # 如果用户的做题记录不为空，则需要进行封装，并且将封装好的信息给大模型进行分析
    else:
        quiz_data = {}
        quiz_data["choice_questions"] = {}
        if total_questions == None:
            total_questions = 0
        quiz_data["choice_questions"]["total_questions"] = total_questions
        if correct_answers == None:
            correct_answers = 0
        quiz_data["choice_questions"]["correct_answers"] = correct_answers
        if incorrect_analysis == None:
            incorrect_analysis = ""
        quiz_data["choice_questions"]["incorrect_analysis"] = incorrect_analysis
        if incorrect_analysis == None:
            incorrect_analysis = ""
        quiz_data["reading_comprehension"] = reading_comprehension
        quiz_data["essay"] = essay
        quiz_data["translation"] = translation
        # print(quiz_data)
        # print(quiz_data)
        # analyze_quiz_performance(quiz_data)
        # print(result)
        asyncio.run(analyze_quiz_performance(quiz_data))

# Run the main function until it completes
# asyncio.run(main())
